package com.myk.game.gobangchess.rooms;

import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.signs.GroundSign;
import com.myk.game.gobangchess.signs.TitleSign;
import com.myk.game.gobangchess.utils.GridsUtils;
import com.myk.game.gobangchess.rooms.absrooms.AbsOneTwoTwoTwoStepRoom;
import com.myk.game.gobangchess.signs.ColorSign;

import java.util.ArrayList;
import java.util.List;

/**
 * 双线五子棋
 */
public class TwoLineGoBangRoom extends AbsOneTwoTwoTwoStepRoom {

    public TwoLineGoBangRoom(String roomName) {
        super(roomName, "\t\t\t\t由okjb发明的新棋，除先手第一步落一子外，每步落两子，两子落在同一直线和斜线上判负，此外也是连五获胜。", "双线五子棋", BoardStyleData.getGoBangStyle(15, 15), true, true);
    }

    @Override
    protected WinState checkWin(int row, int col) {
        if (isOnSameLine(row, col)) {
            if (firstPoint[2] == 1) {
                return new WinState(WinMode.WHITE_WIN, "黑方犯规-" + player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
            }
            else {
                return new WinState(WinMode.BLACK_WIN, "白方犯规-" + player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
            }
        }

        int winValue = 0;

        int[][] dxdy = {{1, 0}, {-1, 1}, {0, 1}, {1, 1}};
        for (int i = 0; i < dxdy.length; i++) {
            int dx = dxdy[i][0], dy = dxdy[i][1];

            int length = getJudgeLength(row, col, dx, dy) + getJudgeLength(row, col, -dx, -dy) - 1;
            if (length >= 5 && winValue == 0) {
                winValue = (curGrids[row][col] + 1) % 2 + 1;
            }
        }

        boolean gridFull = GridsUtils.getDataCount(curGrids, 0) == 0;

        if (winValue == 1) {
            return new WinState(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
        }
        else if (winValue == 2) {
            return new WinState(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
        }
        else if (gridFull) {
            return new WinState(WinMode.BOTH_DRAW, player_black.getNickNameOrTemp() + "-黑棋战平" + player_white.getNickNameOrTemp() + "-白棋");
        }
        else {
            return null;
        }
    }

    @Override
    public String getRuleText() {
        return "黑棋先落一枚棋子，\n" +
                "随后白黑双方轮流落下两枚棋子。\n" +
                "这两枚棋子不能落在同一直线/斜线\n" +
                "获胜条件：形成五子一线\n" +
                "落败条件：一步落下的两子同线\n" +
                "和棋条件：无棋可走";
    }

    @Override
    public String getGameInfo() {
        signList.clear();

        signList.addAll(tempPointSigns);

        float titleSize = 0.3f;
        float bY = (curGrids.length + 0.2f) / curGrids.length;
        signList.add(new TitleSign(0.3f, bY, 2, "#注意不要落子在浅红色方格上，会直接犯规失败！", "#FFFF0000", titleSize));

        return super.getGameInfo();
    }

    @Override
    protected void updateTempPointSigns() {
        tempPointSigns.clear();
        if (firstPoint != null && secondPoint != null) {
            if (isOnSameLine(secondPoint[0], secondPoint[1]) && firstPoint[2] == secondPoint[2]) {
                List<Integer> ids = new ArrayList<>();
                int rAdd = 0;
                if (secondPoint[0] < firstPoint[0]) {
                    rAdd = 1;
                }
                else if (secondPoint[0] > firstPoint[0]) {
                    rAdd = -1;
                }
                int cAdd = 0;
                if (secondPoint[1] < firstPoint[1]) {
                    cAdd = 1;
                }
                else if (secondPoint[1] > firstPoint[1]) {
                    cAdd = -1;
                }
                for (int i = secondPoint[0], j = secondPoint[1]; i != firstPoint[0] || j != firstPoint[1]; i += rAdd, j += cAdd) {
                    ids.add(getIndex(i, j));
                }
                ids.add(getIndex(firstPoint[0], firstPoint[1]));
                tempPointSigns.add(new ColorSign(ids, "#66EE6666")); //浅红色
            }
            tempPointSigns.add(new GroundSign(getIndex(firstPoint[0], firstPoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1.0f, 0, 0));
            tempPointSigns.add(new GroundSign(getIndex(secondPoint[0], secondPoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1.0f, 0, 0));
        }
        else if (firstPoint != null) {
            if (step != 1 || GridsUtils.getDataCount(curGrids, 2) != 0) { //先手第一步不显示禁着点
                List<int[]> cantPutPosList = getCantPutPosList(); //获取禁着点集合
                if (cantPutPosList.size() > 0) {
                    List<Integer> ids = new ArrayList<>();
                    for (int[] canMovedPos : cantPutPosList) {
                        ids.add(getIndex(canMovedPos[0], canMovedPos[1]));
                    }
                    tempPointSigns.add(new ColorSign(ids, "#66EE6666")); //浅红色
                }
            }
            tempPointSigns.add(new GroundSign(getIndex(firstPoint[0], firstPoint[1]), "#00000000", ColorCost.NEW_PUT_POINT, 1.0f, 0, 0));
        }
    }

    private boolean isOnSameLine(int row, int col) {
        if (firstPoint == null) {
            return false;
        }
        int lastRow = firstPoint[0];
        int lastCol = firstPoint[1];
        if (lastRow == row || lastCol == col) {
            return true;
        }
        if (Math.abs(lastRow - row) == Math.abs(lastCol - col)) {
            return true;
        }
        return false;
    }

    private List<int[]> getCantPutPosList() {
        List<int[]> canMovedPosList = new ArrayList<>();
        int h = curGrids.length;
        int w = curGrids[0].length;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if (isOnSameLine(i, j)) {
                    canMovedPosList.add(new int[]{i, j});
                }
            }
        }
        return canMovedPosList;
    }
}
